"""
页面基类模块

提供所有页面共有的基础操作方法，是页面对象模型的核心基类。
封装了Selenium的常用操作，如元素查找、输入、点击等。
"""

from selenium.webdriver.support.select import Select
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from utils.logger import log
from utils.timer import sleep
from selenium.webdriver.common.action_chains import ActionChains


class Base:
    """页面基类
    
    封装了Selenium的基础操作方法，
    所有具体页面类都应继承此类。
    """
    
    def __init__(self, driver):
        """
        初始化页面基类
        :param driver: WebDriver实例
        """
        self.driver = driver

    def base_find(self, loc, timeout=15, poll=0.5):
        """
        智能查找元素，带等待机制
        :param loc: 元素定位器，格式为(By.XXX, "定位值")
        :param timeout: 等待超时时间，默认30秒
        :param poll: 轮询间隔时间，默认0.5秒
        :return: WebElement实例
        """
        try:
            log.info(f"查找元素: {loc}")
            element = WebDriverWait(self.driver, timeout, poll).until(
                EC.visibility_of_element_located(loc)
            )
            return element
        except Exception as e:
            log.error(f"查找元素失败: {loc}, 错误: {str(e)}")
            raise

    def base_input(self, loc, text):
        """
        在指定元素中输入文本
        :param loc: 元素定位器
        :param text: 要输入的文本
        """
        el = self.base_find(loc)
        el.clear()
        if text is not None:
            el.send_keys(text)
            log.info(f"在元素 {loc} 中输入文本: {text}")

    def base_click(self, loc):
        """
        点击指定元素
        :param loc: 元素定位器
        """
        try:
            self.base_find(loc).click()
            sleep()
            log.info(f"点击元素: {loc}")
        except Exception as e:
            log.error(f"点击元素失败: {loc}, 错误: {str(e)}")
            raise

    def base_get_text(self, loc):
        """
        获取元素的文本内容
        :param loc: 元素定位器
        :return: 元素文本
        """
        text = self.base_find(loc).text
        log.info(f"获取元素 {loc} 的文本: {text}")
        return text

    def base_get_title(self):
        """
        获取当前页面的标题
        :return: 页面标题
        """
        title = self.driver.title
        log.info(f"当前页面标题: {title}")
        return title

    def base_alert_confirm(self):
        """确认JavaScript警告框"""
        self.driver.switch_to.alert.accept()
        log.info("确认了警告框")

    def base_is_displayed(self, loc):
        """
        检查元素是否可见
        :param loc: 元素定位器
        :return: 布尔值，表示元素是否可见
        """
        is_displayed = self.base_find(loc).is_displayed()
        log.info(f"元素 {loc} 的可见状态: {is_displayed}")
        return is_displayed

    def base_keep_press(self, loc, time_seconds):
        """
        长按指定元素
        :param loc: 元素定位器
        :param time_seconds: 长按时间（秒）
        """
        element = self.base_find(loc)
        ActionChains(self.driver).click_and_hold(element).perform()
        log.info(f"长按元素: {loc}")
        sleep(time_seconds)
        ActionChains(self.driver).release(element).perform()
        log.info(f"释放长按元素: {loc}")

    def base_select(self, loc, text):
        """
        在下拉框中选择指定文本的选项
        :param loc: select元素的定位器
        :param text: 要选择的文本
        """
        Select(self.base_find(loc)).select_by_visible_text(text)
        log.info(f"在下拉框 {loc} 中选择: {text}")

    def base_refresh(self):
        """刷新当前页面"""
        self.driver.refresh()
        log.info("刷新页面")

    def base_quit(self):
        """退出浏览器"""
        self.driver.quit()
        log.info("退出浏览器")
